package com.lzj.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lzj.admin.pojo.SaleList;
import com.lzj.admin.pojo.SaleListPayment;
import com.lzj.admin.mapper.SaleListPaymentMapper;
import com.lzj.admin.query.SaleListPaymentQuery;
import com.lzj.admin.service.ISaleListPaymentService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzj.admin.service.ISaleListService;
import com.lzj.admin.utils.AssertUtil;
import com.lzj.admin.utils.PageResultUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

/**
 * <p>
 * 销售单支付明细表 服务实现类
 * </p>
 *
 * @author luoyoumou
 * @since 2023-02-08
 */
@Service
public class SaleListPaymentServiceImpl extends ServiceImpl<SaleListPaymentMapper, SaleListPayment> implements ISaleListPaymentService {

    @Resource
    private ISaleListService saleListService;

    @Override
    public Map<String, Object> saleListPaymentList(SaleListPaymentQuery saleListPaymentQuery) {
        IPage<SaleListPayment> page = new Page<SaleListPayment>(saleListPaymentQuery.getPage(),saleListPaymentQuery.getLimit());
        page = this.baseMapper.querySaleListPaymentByParams(page,saleListPaymentQuery);
        return PageResultUtil.getResult(page.getTotal(),page.getRecords());
    }

    /**
     * 销售表单 - 结算功能的实现(销售单据支付明细添加)
     * @param saleListPayment
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void saveSaleListPayment(SaleListPayment saleListPayment) {
        // 如果是手工结算，需作相关校验
        if(!(1==saleListPayment.getPayType())){
            //通过id，判断销售记录是否存在
            SaleList saleList = saleListService.getById(saleListPayment.getSaleListId());
            AssertUtil.isTrue(null == saleList || 1 == saleList.getIsDel(),"待结算的销售单记录不存在!");
            // 判断交易状态，getState()==2 表示已经支付
            AssertUtil.isTrue(saleList.getState()==2,"该销售单已结算，无需再添加支付记录!");
            // 判断支付金额是否合法
            // AssertUtil.isTrue(!(0<saleListPayment.getAmountPaid()),"必须满足：支付金额 >0 !");
            AssertUtil.isTrue(!(BigDecimal.ZERO.compareTo(saleListPayment.getAmountPaid())==-1),"必须满足：支付金额 > 0 !");

            // AssertUtil.isTrue(!(saleListPayment.getAmountPaid() <= saleList.getAmountNotPaid()),"必须满足：支付金额 <= 未付金额 !");
            AssertUtil.isTrue(!(saleListPayment.getAmountPaid().compareTo(saleList.getAmountNotPaid())<1),"必须满足：支付金额 <= 未付金额 !");
            AssertUtil.isTrue(BigDecimal.ZERO.compareTo(saleListPayment.getAmountDiscounts())==1,"必须满足：优惠金额 >= 0 !");
            if(BigDecimal.ZERO.compareTo(saleListPayment.getAmountDiscounts())==-1){ // 如果优惠金额 大于 0
                AssertUtil.isTrue(!(saleList.getAmountNotPaid().compareTo(saleListPayment.getAmountPaid().add(saleListPayment.getAmountDiscounts()))==0) ,"必须满足：实付金额 + 优惠金额 = 未付金额 ！");
                // 实付金额 >= 优惠金额
                AssertUtil.isTrue(saleList.getAmountPaid().add(saleListPayment.getAmountPaid()).compareTo(saleListPayment.getAmountDiscounts()) < 1,"挣钱不容易，不要卖血；必须满足：实付金额 >= 优惠金额 ！");
                saleList.setAmountDiscounts(saleListPayment.getAmountDiscounts());
            }

            Date updateDate = new Date();

            //更新销售表单 支付金额
            // saleList.setAmountPaid(saleList.getAmountPaid()+saleListPayment.getAmountPaid());
            saleList.setAmountPaid(saleList.getAmountPaid().add(saleListPayment.getAmountPaid()));
            saleList.setUpdateUserId(saleListPayment.getUpdateUserId());
            saleList.setUpdateDate(updateDate);
            //调用父类更新方法，根据id执行更新，取反结果为真，更新失败
            AssertUtil.isTrue(!(saleListService.updateById(saleList)),"销售单支付记录添加失败-@5!");

            saleListPayment.setPayType(2);
            saleListPayment.setIsDel(0);
            saleListPayment.setSaleNumber(saleList.getSaleNumber());
            saleListPayment.setCreateDate(updateDate);
            saleListPayment.setUpdateDate(updateDate);
            saleListPayment.setRemarks(saleListPayment.getRemarks().trim());
            AssertUtil.isTrue(!(this.save(saleListPayment)), "销售单支付记录添加失败-@6!");
        } else { // 销售单据支付明细添加(做销售单的时候，自动添加)
            saleListPayment.setIsDel(0);
            AssertUtil.isTrue(!(this.save(saleListPayment)), "销售单记录添加失败-@7!");
        }
    }

    /**
     * 销售单据支付明细修改：
     *   非最近的一笔支付明细记录，不能被修改(主要是考虑做销售单 或结算的时候，不小心 输错 “支付金额” 的修正）
     *   已结算(已付款)的订单，其支付明细不能被修改
     * @param saleListPayment
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void updateSaleListPayment(SaleListPayment saleListPayment) {
        SaleListPayment tempSaleListPayment = this.getOne(new QueryWrapper<SaleListPayment>().eq("is_del",0).eq("sale_list_id",saleListPayment.getSaleListId()).last("order by id desc limit 1"));
        AssertUtil.isTrue(null == tempSaleListPayment, "销售单支付记录不存在");
        AssertUtil.isTrue(!(tempSaleListPayment.getId() == saleListPayment.getId()), "非销售单的最近一笔支付明细记录，不能被修改！");

        //通过id，判断销售记录是否存在
        SaleList saleList = saleListService.getById(saleListPayment.getSaleListId());
        AssertUtil.isTrue(null == saleList || 1 == saleList.getIsDel(),"销售单不存在!");
        // 判断交易状态，getState()==2 表示已经支付
        AssertUtil.isTrue(saleList.getState()==2,"该销售单已结算，其支付记录不能被修改!");
        // 判断支付金额是否合法
        // AssertUtil.isTrue(!(0<saleListPayment.getAmountPaid()),"必须满足：支付金额 >0 !");
        AssertUtil.isTrue(!(BigDecimal.ZERO.compareTo(saleListPayment.getAmountPaid())==-1),"必须满足：支付金额 > 0 !");
        // AssertUtil.isTrue(!(saleListPayment.getAmountPaid() <= tempSaleListPayment.getAmountPaid()+saleList.getAmountNotPaid()),"必须满足：支付金额 <= 未付金额 !");
        AssertUtil.isTrue(!(saleListPayment.getAmountPaid().compareTo(tempSaleListPayment.getAmountPaid().add(saleList.getAmountNotPaid()))<1),"必须满足：支付金额 <= 未付金额 !");
        AssertUtil.isTrue(BigDecimal.ZERO.compareTo(saleListPayment.getAmountDiscounts())==1,"必须满足：优惠金额 >= 0 !");
        if(BigDecimal.ZERO.compareTo(saleListPayment.getAmountDiscounts())==-1){ // 如果优惠金额 大于 0
            // 这里要注意一下逻辑：修改后的付款金额 + 优惠金额 - 修改前的付款金额
            AssertUtil.isTrue(!(saleList.getAmountNotPaid().compareTo(saleListPayment.getAmountPaid().add(saleListPayment.getAmountDiscounts()).add(tempSaleListPayment.getAmountPaid().negate()))==0) ,"必须满足：实付金额 + 优惠金额 = 未付金额 ！");
            // 这里要注意一下逻辑：实付金额 + 修改后的支付金额 - 修改前的支付金额 >= 优惠金额
            AssertUtil.isTrue(saleList.getAmountPaid().add(saleListPayment.getAmountPaid()).add(tempSaleListPayment.getAmountPaid()).compareTo(saleListPayment.getAmountDiscounts()) < 1,"挣钱不容易，不要卖血；必须满足：实付金额 >= 优惠金额 ！");
            saleList.setAmountDiscounts(saleListPayment.getAmountDiscounts());
        }

        Date updateDate = new Date();

        //更新销售单 支付金额 ( 加上 “修改后的金额” 并 减去 "修改前的金额" )
        saleList.setAmountPaid(saleList.getAmountPaid().add(saleListPayment.getAmountPaid()).add(tempSaleListPayment.getAmountPaid().negate()));
        saleList.setUpdateUserId(saleListPayment.getUpdateUserId());
        saleList.setUpdateDate(updateDate);
        //调用父类更新方法，根据id执行更新，取反结果为真，更新失败
        AssertUtil.isTrue(!(saleListService.updateById(saleList)),"销售单支付记录修改失败-@1!");

        saleListPayment.setPayType(2);
        saleListPayment.setRemarks(saleListPayment.getRemarks().trim());
        saleListPayment.setUpdateDate(updateDate);
        AssertUtil.isTrue(!(this.updateById(saleListPayment)),"销售单支付记录修改失败-@2!");

    }

    /**
     * 销售单据支付明细删除
     *   非最近一笔支付明细记录，不能被删除
     *   已结算(已付款)的订单，其支付明细不能被删除
     * @param id
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void deleteSaleListPayment(Integer id,Integer userId) {
        SaleListPayment saleListPayment = this.getById(id);
        AssertUtil.isTrue(null == saleListPayment, "销售单支付记录不存在");

        SaleListPayment tempSaleListPayment = this.getOne(new QueryWrapper<SaleListPayment>().eq("is_del",0).eq("sale_list_id",saleListPayment.getSaleListId()).last("order by id desc limit 1"));
        AssertUtil.isTrue(!(tempSaleListPayment.getId() == saleListPayment.getId()), "非销售单的最近一笔支付明细记录，不能被删除！");

        //通过id，判断销售记录是否存在
        SaleList saleList = saleListService.getById(saleListPayment.getSaleListId());
        AssertUtil.isTrue(null == saleList || 1 == saleList.getIsDel(),"销售单不存在!");
        // 判断交易状态，getState()==2 表示已经支付
        AssertUtil.isTrue(saleList.getState()==2,"该销售单已结算，其支付记录不能被删除!");

        // 既然：已结算的订单不能被删除，那么就无需考虑 优惠金额的事情了

        Date updateDate = new Date();
        //更新销售单 支付金额
        saleList.setAmountPaid(saleList.getAmountPaid().add(saleListPayment.getAmountPaid().negate()));
        saleList.setUpdateUserId(userId);
        saleList.setUpdateDate(updateDate);
        //调用父类更新方法，根据id执行更新，取反结果为真，更新失败
        AssertUtil.isTrue(!(saleListService.updateById(saleList)),"销售单支付记录删除失败-@1!");

        saleListPayment.setUpdateUserId(userId);
        saleListPayment.setUpdateDate(updateDate);
        saleListPayment.setIsDel(1);
        AssertUtil.isTrue(!(this.updateById(saleListPayment)),"销售单支付记录删除失败-@2!");
    }

}
